package com.fau.cm.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Hibernate;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fau.cm.entity.MedicalAdmin;
import com.fau.cm.entity.MedicalGroup;
import com.fau.cm.entity.MedicalPlatform;
import com.fau.cm.entity.MedicalResource;
import com.fau.cm.entity.MedicalRole;
import com.fau.cm.service.IUserManagerService;
import com.fau.cm.util.Page;
import com.fau.cm.util.ParamUtil;
import com.fau.cm.util.SystemConfig;


@Service
@Transactional(readOnly = true)
public class UserManagerService extends BaseService implements IUserManagerService {
	
	protected final MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
	private Md5PasswordEncoder encoder;

	@SuppressWarnings("deprecation")
	@Override
	public MedicalAdmin findUserByName(String username) {
		MedicalAdmin admin = (MedicalAdmin) iBaseDao.getObjectByHql("from MedicalAdmin a where a.username = ?", username);
		if (ObjectUtils.equals(null, admin)) 
			throw new UsernameNotFoundException(messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);
			Hibernate.initialize(admin.getRoleSet());
			if(!StringUtils.equals(SystemConfig.SUPER_ADMIN, admin.getIsSuper())) Hibernate.initialize(admin.getGroup());
		if(0 == admin.getRoleSet().size())
			throw new UsernameNotFoundException(messages.getMessage("JdbcDaoImpl.noAuthority", new Object[] {username}, "User {0} has no GrantedAuthority"), username);
		return admin;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<MedicalResource> findAllResource() {
		List<MedicalResource> list = iBaseDao.getBySql("from MedicalResource a where a.typeName = ?", null, SystemConfig.CM_SYSTEM_TYPE);
		for(MedicalResource mr : list) {
			Hibernate.initialize(mr.getRoleSet());
		}
		return list;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<MedicalResource> findRootResource() {
		List<MedicalResource> list = this.iBaseDao.getBySql("from MedicalResource a where a.isMenus=? ", null, SystemConfig.ROOT_RESOURCE_TYPE);
		for(MedicalResource mr : list) {
			Hibernate.initialize(mr.getRoleSet());
		}
		return list;
	}
	
	public List<MedicalResource> loadMenu() {
		MedicalAdmin user = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<MedicalResource> list = new ArrayList<MedicalResource>();
		for(MedicalRole mr : user.getRoleSet()) {
			MedicalRole role = (MedicalRole) iBaseDao.getObject(MedicalRole.class, mr.getId());
			for(MedicalResource resource : role.getResourceSet()) {
				if(SystemConfig.IS_MENUS == resource.getIsMenus() && SystemConfig.CM_SYSTEM_TYPE.equals(resource.getTypeName())){
					list.add(resource);
				}
			}
		}
		for(int i = 0; i < list.size(); i++) {
			for(int j = list.size() - 1; j > i; j--) {
				if(list.get(i).getId().equals(list.get(j).getId())){
					list.remove(j);
				}
			}
		}
		return list;
	}
	
	public Md5PasswordEncoder getEncoder() {
		return encoder;
	}

	@Resource
	public void setEncoder(Md5PasswordEncoder encoder) {
		this.encoder = encoder;
	}

	@Override
	public int countUnreadNum() {
		MedicalAdmin user = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		int num = this.iBaseDao.getIntCount("select count(*) from MedicalMessage a where a.isRead=? and a.hospitalId=? and a.uid=? ", 0
				,user.getEnterpriseId()
				,user.getId());
		return num;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	public void deleteMassage(String ids) {
		String[] idArray = ids.split("-");
		for(String id : idArray){
			this.iBaseDao.updateHql("delete from MedicalMessage a where a.id=? ", id);
		}
	}

	@Override
	public Page findMassageByPage(MedicalAdmin admin, Map<String, Object> map) {
		StringBuilder statusSql = new StringBuilder("from MedicalMessage a where a.hospitalId=? and a.uid=? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalMessage a where a.hospitalId=? and a.uid=? ");
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		objectList.add(admin.getId());
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		return page;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	public void setRead() {
		MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		this.iBaseDao.updateHql("update MedicalMessage a set a.isRead=1 where a.hospitalId=? and a.uid=? ", admin.getEnterpriseId(),admin.getId());
	}

	@Override
	public List<MedicalPlatform> findAllCurSerCenter(MedicalAdmin admin) {
		@SuppressWarnings("unchecked")
		List<MedicalPlatform> list = this.iBaseDao.getBySql("from MedicalPlatform a where a.eid=? and a.platformType=? ", null, admin.getEnterpriseId(),SystemConfig.CALL_CENTER_TYPE);
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<MedicalGroup> findAllCurSerGroup(String cid) {
		List<MedicalGroup> list = new ArrayList<MedicalGroup>();
		if(StringUtils.isNotBlank(cid)) {
			list = this.iBaseDao.getBySql("from MedicalGroup a where a.platform.id=? ", null, cid);
		}else {
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			if(!SystemConfig.SUPER_ADMIN.equals(admin.getIsSuper())) {
				list = this.iBaseDao.getBySql("from MedicalGroup a where a.platform.id=? ", null, admin.getGroup().getPlatform().getId());
			}
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<MedicalAdmin> findCurSerByGroupId(String groupId) {
		List<MedicalAdmin> list = new ArrayList<MedicalAdmin>();
		if(StringUtils.isBlank(groupId)){
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			if(!SystemConfig.SUPER_ADMIN.equals(admin.getIsSuper())) {
				list = this.iBaseDao.getBySql("from MedicalAdmin a where a.group.id=? ", null, admin.getGroup().getId());
			}
		}else{
			list = this.iBaseDao.getBySql("from MedicalAdmin a where a.group.id=? ", null, groupId);
		}
		
		return list;
	}

}
